package net.sudot.chess.business.model;

import lombok.Getter;

import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import java.math.BigDecimal;
import java.time.Instant;

/**
 * 基础订单
 *
 * @author tangjialin on 2018-03-21.
 */
@Getter
@MappedSuperclass
@SuppressWarnings("unchecked")
public abstract class BaseOrder<E extends BaseOrder> extends BaseEntity<E> {
    /** 订单所属用户 */
    private Long userId;
    /**
     * 订单所属对象
     * <pre>
     * {@link OrderRecharge}是充值配置主键.即:target = {@link RechargeConfig#id}
     * {@link OrderGame}是游戏房间主键.即:target = {@link Room#id}
     * {@link OrderBail}是押金配置主键.即:target = {@link BailConfig#id}
     * </pre>
     */
    private Long target;
    /** 编号 */
    private String sn;
    /** 价格(商品标示价格,非支付价格) */
    private BigDecimal price;
    /** 实际需要支付的金额 */
    private BigDecimal paymentAmount;
    /** 已付金额 */
    private BigDecimal paidAmount;
    /** 赠送(正数)或抵扣(负数)金额 */
    private BigDecimal exchangeAmount;
    /** 赠送(正数)或抵扣(负数)积分 */
    private Long exchangePoint;
    /** 是否赠送(正数)或抵扣(负数)余额 */
    private Boolean isExchangeAmount;
    /** 是否赠送(正数)或抵扣(负数)积分 */
    private Boolean isExchangePoint;
    /** 订单完成时间 */
    private Instant completeDate;
    /** 备注 */
    private String memo;

    public E setUserId(Long userId) {
        this.userId = userId;
        return (E) this;
    }

    public E setTarget(Long target) {
        this.target = target;
        return (E) this;
    }

    public E setSn(String sn) {
        this.sn = sn;
        return (E) this;
    }

    public E setPrice(BigDecimal price) {
        this.price = price;
        return (E) this;
    }

    public E setPaymentAmount(BigDecimal paymentAmount) {
        this.paymentAmount = paymentAmount;
        return (E) this;
    }

    public E setPaidAmount(BigDecimal paidAmount) {
        this.paidAmount = paidAmount;
        return (E) this;
    }

    public E setExchangeAmount(BigDecimal exchangeAmount) {
        this.exchangeAmount = exchangeAmount;
        return (E) this;
    }

    public E setExchangePoint(Long exchangePoint) {
        this.exchangePoint = exchangePoint;
        return (E) this;
    }

    public E setIsExchangeAmount(Boolean exchangeAmount) {
        isExchangeAmount = exchangeAmount;
        return (E) this;
    }

    public E setIsExchangePoint(Boolean exchangePoint) {
        isExchangePoint = exchangePoint;
        return (E) this;
    }

    public E setCompleteDate(Instant completeDate) {
        this.completeDate = completeDate;
        return (E) this;
    }

    public E setMemo(String memo) {
        this.memo = memo;
        return (E) this;
    }

    /**
     * 获取应付金额
     *
     * @return 应付金额
     */
    @Transient
    public abstract BigDecimal getPayableAmount();

    /**
     * 获取应退金额
     *
     * @return 应退金额
     */
    @Transient
    public abstract BigDecimal getRefundableAmount();

    /**
     * 判断是否已过期
     *
     * @return 是否已过期
     */
    @Transient
    public abstract boolean hasExpired();

}